The Unofficial Newsletter of Delphi Users - by Robert Vivrette

More With The Taskbar

by Francois Gaillard

Just a few quick tips on using the Windows TaskBar...

What's up?

There is a well known trick (search the Web for "Shell_TrayWnd", you'll see...) to hide or show the taskbar with the

    ShowWindow(TaskBarHandle, SW_HIDE);
or
    ShowWindow(TaskBarHandle, SW_SHOW);
commands. There is a remaining problem that I haven't seen addressed: if you maximize a window after hiding the taskbar, you'll get an empty area where the taskbar used to be and you don't get a full-screen window. You may also need to temporarily disable the AlwaysOnTop feature of the taskbar, allowing your Forms to pass above the taskbar.

Screen Area
 

A quite easy solution is to use the GetSystemMetrics, GetWindowRect and SystemParametersInfo API routines.

procedure FullScreenArea;
{ set workarea to full screen }
var
  rcWork: TRect;
begin
  rcWork.Top:=0;
  rcWork.Left:=0;
  rcWork.Bottom:=GetSystemMetrics(SM_CYSCREEN);
  rcWork.Right:=GetSystemMetrics(SM_CXSCREEN);
  SystemParametersInfo (SPI_SETWORKAREA, 0, @rcWork, SPIF_SENDCHANGE);
end;

procedure StandardArea;
{ set workarea to standard screen (= excluding taskbar) }
var
  hApp: HWND;
  rcApp, rcWork: TRect;
begin
  { prepare a default fullscreen workarea }
  rcWork.Top:=0;
  rcWork.Left:=0;
  rcWork.Bottom:= GetSystemMetrics(SM_CYSCREEN);
  rcWork.Right:= GetSystemMetrics(SM_CXSCREEN);

  { get the taskbar handle }
  hApp := FindWindow('Shell_TrayWnd', '');
  if hApp <> 0 then begin
    { get the size of the taskbar }
    GetWindowRect(hApp, rcApp);
    { cut the workarea to place the taskbar }
    if rcApp.Right<rcWork.Right then
      rcWork.Left:=rcApp.Right; { bar on left edge }
    if rcApp.Bottom<rcWork.Bottom then
      rcWork.Top:=rcApp.Bottom; { bar on top edge }
    if rcApp.Left>0 then
      rcWork.Right:=rcApp.Left; { bar on right edge }
    if rcApp.Top>0 then
      rcWork.Bottom:=rcApp.Top; { bar on bottom edge }
  end;

  { set workarea }
  SystemParametersInfo (SPI_SETWORKAREA, 0, @rcWork, SPIF_SENDCHANGE );
end; { StandardArea }
 

TaskBar On Top or Not?

The trick is to use API's SetWindowPos with HWND_TOPMOST or HWND_BOTTOM as 2nd parameter.

procedure TaskBarOnTop(bOnTop: boolean);
var
  hApp: HWND;
begin
  { get the taskbar handle }
  hApp := FindWindow('Shell_TrayWnd', '');
  if hApp <> 0 then begin
    if   bOnTop then
      setWindowPos(hApp,HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE)
    else
      setWindowPos(hApp,HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE);
  end;
end;

procedure SetTaskBarOnTop;
begin
  TaskBarOnTop(True);
end;

procedure SetTaskBarAtBottom;
begin
  TaskBarOnTop(False);
end;
 

Showing or Hiding TaskBar...

Straightforward using the preceding screen area procedures.

procedure HideTaskBar;
var
  hApp: HWND;
  rcWork: TRect;
begin
  { get the taskbar handle }
  hApp := FindWindow('Shell_TrayWnd', '');
  if hApp <> 0 then begin
    { hide taskbar }
    ShowWindow(hApp, SW_HIDE);
    { set workarea to full screen }
    FullScreenArea;
  end;
end;

procedure ShowTaskBar;
var
  hApp: HWND;
  rcApp, rcWork: TRect;
begin
  { get the taskbar handle }
  hApp := FindWindow('Shell_TrayWnd', '');
  if hApp <> 0 then begin
    { restore taskbar }
    ShowWindow(hApp, SW_RESTORE);
    { set workarea excluding taskbar }
    StandardArea;
  end;
end;